import { Socket } from 'socket.io'
import { verifyToken } from '../middlewares/auth'
import { ChatService } from '../services/chat/ChatService'
import { GiftService } from '../services/gift/GiftService'
import { RoomService } from '../services/room/RoomService'
import { StreamingService } from '../services/streaming/StreamingService'
import { logger } from '../utils/logger'

interface Services {
  chatService: ChatService
  roomService: RoomService
  streamingService: StreamingService
  giftService: GiftService
}

export const socketHandler = (socket: Socket, services: Services) => {
  const { chatService, roomService, streamingService, giftService } = services

  // 用户认证
  socket.on('authenticate', async (token: string) => {
    try {
      const user = await verifyToken(token)
      if (user) {
        socket.data.user = user
        socket.emit('authenticated', { userId: user._id })
        logger.info(`用户 ${user._id} 认证成功`)
      }
    } catch (error) {
      socket.emit('error', { message: '认证失败' })
    }
  })

  // 加入房间
  socket.on('join_room', async (roomId: string) => {
    try {
      if (!socket.data.user) {
        throw new Error('未认证')
      }

      await roomService.joinRoom(roomId, socket.data.user._id)
      socket.join(roomId)
      socket.data.roomId = roomId

      // 发送房间信息
      const roomInfo = await roomService.getRoomInfo(roomId)
      socket.emit('room_info', roomInfo)

      // 广播用户加入消息
      socket.to(roomId).emit('user_joined', {
        userId: socket.data.user._id,
        nickname: socket.data.user.nickname,
        level: socket.data.user.level,
      })
    } catch (error) {
      socket.emit('error', { message: error.message })
    }
  })

  // 发送消息
  socket.on('chat_message', async (data: { content: string; type?: string }) => {
    try {
      if (!socket.data.user || !socket.data.roomId) {
        throw new Error('未加入房间')
      }

      const message = await chatService.sendMessage({
        userId: socket.data.user._id,
        roomId: socket.data.roomId,
        content: data.content,
        type: data.type || 'text',
      })

      // 广播消息
      socket.to(socket.data.roomId).emit('new_message', message)
    } catch (error) {
      socket.emit('error', { message: error.message })
    }
  })

  // 发送礼物
  socket.on('send_gift', async (data: { giftId: string; count: number }) => {
    try {
      if (!socket.data.user || !socket.data.roomId) {
        throw new Error('未加入房间')
      }

      const result = await giftService.sendGift({
        userId: socket.data.user._id,
        roomId: socket.data.roomId,
        giftId: data.giftId,
        count: data.count,
      })

      // 广播礼物消息
      socket.to(socket.data.roomId).emit('new_gift', result)
    } catch (error) {
      socket.emit('error', { message: error.message })
    }
  })

  // 开始直播
  socket.on('start_stream', async () => {
    try {
      if (!socket.data.user || !socket.data.roomId) {
        throw new Error('未加入房间')
      }

      const streamInfo = await streamingService.getPushUrl(socket.data.roomId, socket.data.user._id)

      socket.emit('stream_info', streamInfo)
    } catch (error) {
      socket.emit('error', { message: error.message })
    }
  })

  // 心跳检测
  socket.on('ping', () => {
    socket.emit('pong')
  })

  // 断开连接
  socket.on('disconnect', async () => {
    try {
      if (socket.data.roomId && socket.data.user) {
        await roomService.leaveRoom(socket.data.roomId, socket.data.user._id)

        // 广播用户离开消息
        socket.to(socket.data.roomId).emit('user_left', {
          userId: socket.data.user._id,
        })
      }
    } catch (error) {
      logger.error('断开连接错误:', error)
    }
  })

  // 错误处理
  socket.on('error', (error) => {
    logger.error('Socket错误:', error)
    socket.emit('error', { message: '服务器错误' })
  })
}
